package Vue;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

import Controleur.Controleur;
import Model.Motif;

/**
 * Cette class permet de créer et gérer la zone de dessin, c'est là où l'ulisateur dessinera les motifs d'un dessin.
 * 
 * @author Kilian Cousein et Benjamin Tardieu
 */
public class ZoneDeDessin extends JPanel implements MouseListener, MouseMotionListener
{	
//======================================================================//
//============================ Variables ===============================//
//======================================================================//
	
	private Controleur controleur;
	
	private Point positionDebutFigure = new Point();
	private Point positionPrecedente = new Point();
	
	
//======================================================================//
//========================== Constructeurs =============================//
//======================================================================//
	
	/**
	 * Crée une nouvelle instance de <i>ZoneDeDessin</i>.
	 *
	 * @param controleur
	 */
	public ZoneDeDessin(Controleur controleur, int largeur, int hauteur)
    {
    	this.controleur = controleur;
    	
    	this.setBackground(Color.white);
    	this.setPreferredSize(new Dimension(largeur, hauteur));
    	this.revalidate();
    	
    	this.addMouseListener(this);
    	this.addMouseMotionListener(this);
    }
	
	
//======================================================================//
//============================= Méthodes ===============================//
//======================================================================//

	/**
	 * Cette méthode permet de changer la dimension de la zone de dessin.
	 * 
	 * @param dimension Nouvelle dimension de la zone de dessin.
	 */
    public void changerDimensionPaneau(Dimension dimension)
    {
    	this.setPreferredSize(dimension);
    	this.revalidate();
    }
    
    
    /**
     * Cette méthode permet de dessiner tous les motifs du dessin et le motif courant dans la zone de dessin.
     *  
     * @param g
     */
    public void paintAvecMotifCourant(Graphics g)
    {
    	this.paint(g);    	
    	this.controleur.dessiner(g, false);
    }
    
    
    @Override
    public void paint(Graphics g)
    {
    	super.paint(g);
    	
    	
    	this.controleur.dessiner(g, true);
    }

   
//======================================================================//
//====================== Méthodes Implémentées= ========================//
//======================================================================//
    
	@Override
	public void mouseClicked(MouseEvent e)
	{			
		Point positionSouris = new Point(e.getX() / (int) this.controleur.zoomCourant(), e.getY() / (int) this.controleur.zoomCourant());
		int mode = this.controleur.getMode();
		Graphics g = this.getGraphics();
		
		if(e.getClickCount()>=2)
		{
			this.controleur.activeZoneTexte(g);
		}
		else
		{
			if(mode == Controleur.MODE_GOMME)
			{
				if(this.controleur.effacerMotif(positionSouris))
					this.repaint();
			}
			else if(mode == Controleur.MODE_ZOOM)
			{
				this.controleur.zoomIn(positionSouris);
			}
			else if(controleur.motifCourant() != null && controleur.motifCourant().getClass().getCanonicalName() == "Model.Texte" && controleur.getMode() == controleur.MODE_CREATION)
			{
				this.controleur.faireCorrespondreMotif(this.positionDebutFigure, positionSouris);
				this.controleur.activeZoneTexte(g);
				this.controleur.mettreAJourMenu(false);
			}
		}
	}

	
	@Override
	public void mouseEntered(MouseEvent e){ }

	
	@Override
	public void mouseExited(MouseEvent e){ }

	
	@Override
	public void mousePressed(MouseEvent e)
	{  
		Point positionSouris = new Point(e.getX() / (int) this.controleur.zoomCourant(), e.getY() / (int) this.controleur.zoomCourant());
		int mode = this.controleur.getMode();
		Graphics g = this.getGraphics();

		if(mode == Controleur.MODE_SOURIS)
		{
			this.controleur.selectionnerMotif(positionSouris, g);
			this.repaint();
		}
		else if(mode == Controleur.MODE_CREATION)
		{
			this.controleur.nouvelleInstanceMotif();
		}
		
		this.positionDebutFigure.x = positionSouris.x;
		this.positionDebutFigure.y = positionSouris.y;
		
		this.positionPrecedente.x = this.positionDebutFigure.x;
		this.positionPrecedente.y = this.positionDebutFigure.y;
	}

	
	@Override
	public void mouseReleased(MouseEvent e)
	{		
		Motif motifSelectionne = this.controleur.motifCourant();
		Motif motif = this.controleur.getMotif();
		Point positionSouris = new Point(e.getX() / (int) this.controleur.zoomCourant(), e.getY() / (int) this.controleur.zoomCourant());
		int mode = this.controleur.getMode();
		Graphics g = this.getGraphics();
		
		if(motifSelectionne != null)
		{
			if(mode == Controleur.MODE_CREATION)
			{
				if(!this.positionDebutFigure.equals(positionSouris) && motifSelectionne.getClass().getCanonicalName() != "Model.Texte" )
				{
					this.controleur.ajouterMotif();
				}
			}
			else if(mode == Controleur.MODE_SOURIS && motifSelectionne.getSelectionne() && motif != null)
			{
				if(!motif.equals(motifSelectionne))
				{
					this.controleur.modifierMotif(true);
				}
			}
		}
	}

	
	@Override
	public void mouseDragged(MouseEvent e)
	{
		Motif motifSelectionne = this.controleur.motifCourant();
		Point positionSouris = new Point(e.getX() / (int) this.controleur.zoomCourant(), e.getY() / (int) this.controleur.zoomCourant());
		int mode = this.controleur.getMode();
		Graphics g = this.getGraphics();
		
		if(mode == Controleur.MODE_CREATION && motifSelectionne != null && motifSelectionne.getClass().getCanonicalName() != "Model.Texte")
		{
			this.controleur.faireCorrespondreMotif(this.positionDebutFigure, positionSouris);
			this.controleur.mettreAJourMenu(false);
			
			this.paintAvecMotifCourant(g);
		}
		else if(mode == Controleur.MODE_SOURIS && motifSelectionne != null)
		{
			if(this.controleur.getSelectedHandles() == 0)
				this.controleur.deplacerMotif(positionSouris.x - this.positionPrecedente.x, positionSouris.y - this.positionPrecedente.y);
			else
				this.controleur.redimentionnerMotif(positionSouris, this.positionPrecedente);
			
			this.repaint();
			this.positionPrecedente.x = positionSouris.x;
			this.positionPrecedente.y = positionSouris.y;
			g.setPaintMode();
		}
		
		this.controleur.afficherPositionSouris(positionSouris.x, positionSouris.y);
	}

	
	@Override
	public void mouseMoved(MouseEvent e)
	{
		this.controleur.afficherPositionSouris(e.getX() / (int) this.controleur.zoomCourant(), e.getY() / (int) this.controleur.zoomCourant());
	}
}
